package com.dbh.jdk.concurrent;

import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 *  Fork/Join框架使用示例
 *      通过继承ResuriveTask可以携带返回值
 *
 * @author dongbanghui
 * @date 2018/06/06
 */
public class CountTask extends RecursiveTask<Long>{

    /**
     * 定义阈值，如果求和大于这个值，就需要分解
     */
    private static final int THRESHLD = 10000;

    private long start;

    private long end;

    public CountTask(long start, long end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long sum = 0;
        boolean canCopmpute = (end - start) < THRESHLD;
        if(canCopmpute){
            for(long i=start;i<=end;i++){
                sum += i;
            }
        }else{
            //分成100个小任务
            long step = (end - start)/100;
            ArrayList<CountTask> subTasks = new ArrayList<>();
            long pos = start;
            for(int i=0;i<100;i++){
                long lastOne = pos + step;
                if(lastOne>end){
                    lastOne = end;
                }
                CountTask subTask = new CountTask(pos, lastOne);
                pos += step + 1;
                subTasks.add(subTask);
                subTask.fork();
            }
            for(CountTask t : subTasks){
                sum += t.join();
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTask task = new CountTask(0, 200000L);
        ForkJoinTask<Long> result = forkJoinPool.submit(task);
        Long res;
        try {
            // get()方法可以得到最终结果，任务没有结束，主线程就会在get()方法上等待
            res = result.get();
            System.out.println("sum=" + res);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
